Kbuild: the Linux Kernel Build System
Build kernel 相關套件
1 | sudo apt-get install git-core |
查看 Linux kernel
可以在 /lib/modules
查看到目前有哪些 kernel。
且可以在 /boot
找到對應版本
1 | ls /lib/modules |
1 | /boot/grub |
Linux kernel
Kernel
[Linux Kernel] 撰寫 Hello, World module: The init and exit Macros (part 2).
Lesson
Lesson 1: Building and running a new Linux kernel
Video
Linux Boot Process
Kernel Basics
The Linux Kernel Module Programming Guide
The sysfs Filesystem
Trick
Linux Kernel: BUILD_BUG_ON_ZERO() / BUILD_BUG_ON_NULL()
Kernel Module
零散的 code,當需要的時候可以 載入(load)/卸載(unload) 至 kernel。
擴展 kernel 的功能,且不必 reboot kernel
Module 如何進入到 kernel
1 | lsmod # 列出 /proc/modules 的 modules |
當需要的功能不在 kernel 時(not resident in the kernel),
kernel module daemon(kmod
),會執行 modprobe 將 module 載入
modprobe is passed a string in one of two forms:
- module 名稱,如
softdog
orppp
. - A more generic identifier like char−major−10−30.
1 | # kmod -h |
1 | # /etc/modprobe.conf |
接著, modprobe
會瀏覽 /lib/modules/version/modules.dep
,
觀察這個模組載入前還需要載入哪些模組。
/lib/modules/version/modules.dep
藉由 depmod -a
產生且它包含相依模組。
例如: msdos.ko
須要 fat.ko
事先被載入
requested module 有相依於其他模組 如果有定義 symbols(vars of funcs)
最後,modprobe
用 insmod
第一次組入任何 prerequisite 模組至 kernel,然後是 requested module。
modprobe
把 insmod
導至 /lib/modules/version
模組的標準目錄下
1 | insmod /lib/modules/2.6.11/kernel/fs/fat/fat.ko |
There’s a bit more to the story if you want to write your own modules which depend on other modules (we calling this `stacking modules’).
Modversioning
CONFIG_MODVERSIONS
模組不能用 printf
但可以 log information
and warnings
1 |
|
1 | obj−m += hello−1.o |
printk
建議使用 <1> and KERN_ALERT
,在實作真的模組時,可以讓訊息不止只寫在 log 還能顯示給使用者
要小於 console_loglevel
才會顯示到終端機上。
Compiling Kernel Modules
在 kernel 2.6 之後多了一些命名限制,輸出副檔名為 ko
,此外還包含有額外的 modinfo 區塊。
load module & unload module & kernel log
1 | insmod ./hello−1.ko |
1 | modinfo hello−1.ko |
1 | rmmod hello−1 # unload hello-1 |
hello-2.c
init_module()
and cleanup_module()
寫法過時了。請愛用 linux/init 寫法。
1 | /* |
在這份文件你可以看到 obj−y
,但 obj−m
跑去哪了?
你可以看到 obj−$(CONFIG_FOO)
這種東東,而這些變數都存放在 linux/.config
#####
1 | static int hello3_data __initdata = 3; |
1 | MODULE_LICENSE("GPL"); |
1 | # 接參數,`linux/moduleparam.h` |
1 | startstop−objs := start.o stop.o |
1 | version magics |
3
module init 告訴 kernel,你的 module 能提供什麼功能。並設置好,提供給 kernel 去 call
gcc −Wall −o hello hello.c. Run the exectable with strace ./hello.
man 2 writeman 2
for system callman 3
for lib
3.14 name space
- By convention, all kernel prefixes are lowercase.(static variable)
- declare a symbol table and register it with a kernel.
/proc/kallsyms
掌管所有 symbol
Device file
1 | ls −l /dev/hda[1−3] |
brw−rw−−−− 1 root disk 3, 1 Jul 5 2000 /dev/hda1
major number: 1
每個driver 會對應到一個獨特的 major number
minor number: 1
type: b block device
device type
- character devices
- block devices (block devices have a buffer for requests)
/usr/src/linux/Documentation/devices.txt.
character device & block device 解釋
ch 4
1 | struct file_operations fops = { |
1 | struct file_operations fops = { |